home *** CD-ROM | disk | FTP | other *** search
- /*
- % VFFTPASS . C
- %
- % Symmetric Filter for VFFT image transform.
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- This software is copyright (C) by the Lawrence Berkeley Laboratory.
- Permission is granted to reproduce this software for non-commercial
- purposes provided that this notice is left intact.
-
- It is acknowledged that the U.S. Government has rights to this software
- under Contract DE-AC03-765F00098 between the U.S. Department of Energy
- and the University of California.
-
- This software is provided as a professional and academic contribution
- for joint exchange. Thus, it is experimental, and is provided ``as is'',
- with no warranties of any kind whatsoever, no support, no promise of
- updates, or printed documentation. By using this software, you
- acknowledge that the Lawrence Berkeley Laboratory and Regents of the
- University of California shall have no liability with respect to the
- infringement of other copyrights by any part of this software.
-
- For further information about this notice, contact William Johnston,
- Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
- (wejohnston@lbl.gov)
-
- For further information about this software, contact:
- Jin Guojun
- Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
- g_jin@lbl.gov
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % compile: cc -O -o DEST/vfftpass vfftpass.c -lscs1 -lccs -lhips -lm
- */
- char usage[]="options\n\
- [-base #] base value. [Default=0.0], good max=>2.0\n\
- [-c] convex curve. Default is concave curve\n\
- [-hi] high-pass filter. Default is low-pass\n\
- [-f #] elastic scale factor\n\
- [-F #] number of Frames in sample [16]\n\
- [-G] generate plot data of curves only\n\
- [-H #] high pass adjust\n\
- [-L] Linear filter\n\
- [-min #] minimum value at bottom [0.01]\n\
- [-neg] negate filter (1D -hi)\n\
- [-r #] radius factor. default is 1 (100%). Range 0.1 - 1.0\n\
- [-v] verbose\n\
- [<] image [> [-o] VFFT_file]\n";
- /*
- %
- % AUTHOR: Guojun Jin - Lawrence Berkeley Laboratory 5/1/91
- */
-
- #include "vfft_fil.h"
-
- U_IMAGE uimg;
-
- bool dimens, curve_dir, hi_pass, Table, Msg;
- VType *itemp;
- Filter *lkt[3], flr=0.01, sc;
- int dimen1len, h_rows, h_frm, sframes=16,
- r_radius, c_radius, f_radius;
- MType fsize, vsize;
-
-
- main (argc, argv)
- int argc;
- char** argv;
- {
- bool dflag=0, neg=0, vflag, sample=0;
- int f, j;
- Filter base=0, Hbase=.005;
- Filter radius_rate=1., *filter3d, *filter_work;
- register int i;
-
- format_init(&uimg, IMAGE_INIT_TYPE, HIPS, -1, *argv, "S20-1");
-
- for (j=1; j<argc; j++)
- if (*argv[j] == '-'){
- f=1;
- switch (argv[j][f++]) {
- case 'h':
- hi_pass++; break;
- case 'L':
- curve_dir=CURVE_LINEAR; break;
- case 'c':
- curve_dir=CURVE_CONVEX; break;
- case 'b':
- base = GValue(0); break;
- case 'f':
- sc = GValue(0); break;
- case 'F':
- if (GValue(0))
- sframes = atoi(argv[j]+f);
- break;
- case 'G':
- Table++; break;
- case 'H':
- if (GValue(0))
- Hbase = atof(argv[j]+f);
- break;
- case 'm':
- if (GValue(0))
- flr = atof(argv[j]+f);
- break;
- case 'n':
- neg++; break;
- case 'r':
- if (GValue(0))
- radius_rate = atof(argv[j]+f);
- if (radius_rate < 0 || radius_rate > 1.0)
- radius_rate = 1.0;
- break;
- case 'v': Msg++;
- break;
- #ifdef IBMPC
- case 'i':if (GValue(1) && !(in_fp=freopen(argv[j]+f, "rb", stdin)))
- goto ferr;
- break;
- #endif
- case 'o':if (GValue(1) && freopen(argv[j]+f, "wb", stdout)) break;
- ferr: message("File %s can't be opened", argv[j]);
- default:
- usage_n_options(usage, j, argv[j]);
- }
- }
- else if ((in_fp=freopen(argv[j], "r", stdin)) == NULL)
- syserr("can't open frame file %s", argv[j]);
-
- io_test(fileno(in_fp), sample=!iset);
-
- if (sample) { /* no input file */
- uimg.width = uimg.height = 128;
- uimg.frames = sframes;
- uimg.pxl_in = 8;
- uimg.in_form = IFMT_VFFT3D;
- (*uimg.std_swif)(FI_INIT_NAME, &uimg, "VPASS", 0);
- }
- else {
- (*uimg.header_handle)(HEADER_READ, &uimg, 0, 0);
- if (uimg.in_form < IFMT_VFFT3D || uimg.in_form > IFMT_VVFFT3D)
- syserr("image is not a VFFT format");
- vflag = uimg.in_form==IFMT_VVFFT3D || uimg.in_form==IFMT_DVVFFT3D;
- }
- uimg.o_form = uimg.in_form;
- uimg.pxl_out = uimg.pxl_in;
-
- if (!vflag) /* the VVFFT must be in 3D */
- dimens = !(uimg.in_form & 1); /* if it's 2D */
-
- dimen1len = (cln>>1) + 1;
- h_rows = row >> 1;
- h_frm = frm >> 1;
- fsize = row*cln;
- vsize = row*dimen1len;
- f_radius = radius_rate * h_frm;
- r_radius = radius_rate * h_rows;
- c_radius = radius_rate * dimen1len;
- if (f_radius < 1) f_radius = 1;
- if (r_radius < 1) r_radius = 1;
- if (c_radius < 1) c_radius = 1;
-
- lkt[lktCol] = zalloc(cln, sizeof(Filter), "lktcol");
- lkt[lktRow] = zalloc(row, sizeof(Filter), "lktrow");
- lkt[lktFrm] = zalloc(frm, sizeof(Filter), "lktfrm");
-
- if (hi_pass) sc = -sc;
-
- new_curve(lkt[lktCol], c_radius, neg, curve_dir, "samples");
- new_curve(lkt[lktRow], r_radius, neg, curve_dir, "lines");
- new_curve(lkt[lktFrm], f_radius, neg, curve_dir, "layers");
- if (hi_pass){
- register Filter *lktp=lkt[lktFrm];
- for (i=f_radius; i--;)
- lktp[i] = 1. - lktp[i] + .01;
- lktp[0] = Hbase;
- /* for (i=r_radius, lktp=lkt[lktRow]; i--;)
- lktp[i] = 1. - lktp[i];
- for (i=c_radius, lktp=lkt[lktCol]; i--;)
- lktp[i] = 1. - lktp[i];
- */
- if (Msg)
- dump_lkt(lktp, f_radius),
- msg("\n%d hi_pass => floor=%f\n", f_radius,flr);
- }
- if (Table) exit(0); /* only send plot data to stdout */
-
- filter3d = nzalloc(sizeof(*filter3d)<<1, r_radius*c_radius, "filter3d");
- filter_work = filter3d + r_radius * c_radius;
- ibuf = nzalloc(uimg.pxl_in, vsize, "ibuf");
- obuf = zalloc(uimg.pxl_in, vsize, "obuf"); /* be zeroed */
-
- {
- register Filter *filterp=filter3d, *llktp=lkt[lktCol];
- memcpy(filterp, llktp, c_radius*sizeof(*filterp));
- filterp += c_radius;
- for (i=1; i<r_radius; i++){
- register Filter scale = lkt[lktRow][i];
- for (j=0; j<c_radius; j++)
- *filterp++ = scale * llktp[j];
- }
- if (hi_pass){ /* reverse low to high in 2D instead of in 1D */
- filterp = filter3d;
- for (i=r_radius*c_radius; i--;)
- filterp[i] = 1. - filterp[i];
- filterp[0] += Hbase;
- }
- }
- (*uimg.header_handle)(HEADER_WRITE, &uimg, argc, argv, True);
-
- if (sample){
- register Filter *filterp=filter_work;
-
- {
- register float *ibp=ibuf;
- for (i=vsize << 1; i--;)
- ibp[i] = 256.;
- }
- for (f=h_frm; f--;){
- register Filter scale = lkt[lktFrm][f];
- for (i=r_radius*c_radius; i--;)
- filterp[i] = filter3d[i] * scale;
- filtering(ibuf, obuf, base, filterp, f+1);
- }
- if (frm & 1)
- filtering(ibuf, obuf, base, filter3d, f+1);
- for (f=0; f<h_frm; f++){
- register Filter scale = lkt[lktFrm][f];
- for (i=r_radius*c_radius; i--;)
- filterp[i] = filter3d[i] * scale;
- filtering(ibuf, obuf, base, filterp, f+h_frm);
- }
- exit(0);
- }
-
- if (dimens){
- message("%s: 2 dimension filter - %d frames\n", Progname, frm);
- for (f=0; f<frm; f++){
- i = upread(ibuf, uimg.pxl_in, vsize, in_fp);
- if (i != vsize)
- syserr("f%d [%d] read %d", f+1, vsize, i);
- filtering(ibuf, obuf, base, filter3d, f+1);
- }
- }
- else {
- register Filter *filterp=filter_work;
-
- if (hi_pass){
- register Filter scale = lkt[lktFrm][0];
- for (i=r_radius*c_radius; i--;)
- filterp[i] = filter3d[i] * scale;
- }
- else filterp = filter3d;
- i = upread(ibuf, uimg.pxl_in, vsize, in_fp);
- if (i != vsize)
- syserr("f%d [%d] read %d", 1, vsize, i);
- filtering(ibuf, obuf, base, filterp, 1);
-
- for (f=1; f<f_radius; f++){
- register Filter scale = lkt[lktFrm][f];
- filterp = filter_work;
- for (i=r_radius*c_radius; i--;)
- filterp[i] = filter3d[i] * scale;
- i = upread(ibuf, uimg.pxl_in, vsize, in_fp);
- if (i != vsize)
- syserr("f%d [%d] read %d", f+1, vsize, i);
- filtering(ibuf, obuf, base, filterp, f+1);
- }
-
- for (; frm>1 && f<frm-(f_radius<<1); f++){ /* maybe send all 0 frames */
- i = upread(ibuf, uimg.pxl_in, vsize, in_fp);
- if (i != vsize)
- syserr("f%d [%d] read %d", f+1, vsize, i);
- filtering(ibuf, obuf, base, filterp, f+1);
- }
-
- for (; f<frm-1; f++){
- register Filter scale = lkt[lktFrm][frm-1-f];
- filterp = filter_work;
- for (i=r_radius*c_radius; i--;)
- filterp[i] = filter3d[i] * scale;
- i = upread(ibuf, uimg.pxl_in, vsize, in_fp);
- if (i != vsize)
- syserr("f%d [%d] read %d", f+1, vsize, i);
- filtering(ibuf, obuf, base, filterp, f+1);
- }
-
- i = upread(ibuf, uimg.pxl_in, vsize, in_fp);
- if (i != vsize)
- syserr("f%d [%d] read %d", f+1, vsize, i);
- if (hi_pass){
- register Filter scale = lkt[lktFrm][0];
- for (i=r_radius*c_radius; i--;)
- filterp[i] = filter3d[i] * scale;
- }
- else filterp = filter3d;
- filtering(ibuf, obuf, base, filterp, f+1);
- }
- }
-
- new_curve(lkt, maxdiff, neg, curve, name)
- float* lkt;
- int maxdiff;
- char *name;
- {
- Filter rel_val, maxout=1.;
- register Filter scale, vsc=.01*sc/maxdiff + 1;
- register int i;
-
- if (maxdiff==1){
- lkt[0] = 1.;
- return;
- }
- if (curve==CURVE_LINEAR){
- register int rev;
- scale = (maxout-flr)/maxdiff;
- if (neg) for (i=maxdiff; i--;)
- lkt[i] = i * scale + flr;
- else for (i=maxdiff, rev=i-1; i--;)
- lkt[rev-i] = i * scale + flr;
- }
- else{
- {
- register double tmp;
- if (vsc != 1.){
- for (i=tmp=maxdiff; i--;) tmp = tmp*vsc + i;
- scale = (maxout-flr) / tmp;
- }
- else scale = (maxout-flr) / ((maxdiff-1)*maxdiff >> 1);
- }
- if (!neg)
- if (!curve)
- for(i=maxdiff, rel_val=flr; i--;)
- {
- rel_val += (maxdiff-i) * (scale*=vsc);
- if (rel_val > maxout) lkt[i]=maxout;
- else lkt[i] = rel_val;
- }
- else for (i=0, rel_val=maxout; i<maxdiff; i++)
- {
- lkt[i] = rel_val;
- rel_val -= i * (scale*=vsc);
- if (rel_val<flr && !uimg.in_form) rel_val=flr;
- }
- else if (!curve)
- for(i=0, rel_val=flr; i<maxdiff; i++)
- {
- rel_val += i * (scale*=vsc);
- lkt[i] = rel_val;
- }
- else for (i=maxdiff, rel_val=maxout; i--;)
- {
- lkt[i] = rel_val;
- rel_val -= (maxdiff-i) * (scale*=vsc);
- }
- }
- if (Table) GTable(lkt, maxdiff);
- if (Msg)
- dump_lkt(lkt, maxdiff),
- msg("\n%d %s => sc=%f, scale=%f\n", maxdiff, name, sc, scale);
- }
-
- dump_lkt(lktp, n)
- register float *lktp;
- {
- register int i;
- for (i=0; i<n;)
- { message("%10.3f", lktp[i]); if (!(++i & 7)) mesg("\n"); }
- }
-
- GTable(lp, max)
- register float *lp;
- {
- register int i;
- for (i=0; i<max; i++)
- printf("%d %f\n", hi_pass ? max-i : i, *lp++);
- printf("\n\n");
- }
-
- filtering(i_buf, o_buf, base_v, filterp, f)
- VType *i_buf, *o_buf;
- Filter base_v;
- register Filter *filterp;
- {
- register float *ibp=i_buf, *obp=o_buf;
- register int i, j;
-
- if (base_v)
- for (i=r_radius*c_radius; i--;)
- filterp[i] += base_v;
- ibp += hi_pass * ((h_rows-r_radius+1)*dimen1len - c_radius);
-
- for (i=0; i<r_radius; i++){
- register int dis = (row - 1 - (i<<1)) * dimen1len << 1;
- for (j=0; j<c_radius; j++){
- obp[dis] = ibp[dis] * *filterp;
- *obp++ = *ibp++ * *filterp;
- obp[dis] = ibp[dis] * *filterp;
- *obp++ = *ibp++ * *filterp++;
- }
- obp += dimen1len - c_radius << 1;
- ibp += dimen1len - c_radius << 1;
- }
-
- i = fwrite(o_buf, uimg.pxl_in, vsize, out_fp);
- if (i != vsize)
- syserr("f%d [%d] write %d", f, vsize, i);
- }
-